package com.quanyan.sys.service.impl;

import com.quanyan.api.APIResponse;
import com.quanyan.api.enums.ApiResponseEnum;
import com.quanyan.common.Plugin.Page;
import com.quanyan.common.Plugin.PageObj;
import com.quanyan.common.constants.Constants;
import com.quanyan.common.exception.BizException;
import com.quanyan.common.utils.StringUtil;
import com.quanyan.sys.entity.OrgUserExample;
import com.quanyan.sys.entity.Organization;
import com.quanyan.sys.entity.OrganizationExample;
import com.quanyan.sys.mapper.OrgUserMapper;
import com.quanyan.sys.mapper.OrganizationMapper;
import com.quanyan.sys.service.OrgService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * @author songzj
 * @date 16/4/26-11:10
 */
@Service("orgService")
public class OrgServiceImpl implements OrgService {

    @Autowired
    private OrganizationMapper organizationMapper;

    @Autowired
    private OrgUserMapper orgUserMapper;

    @Override
    public APIResponse<Organization> insert(Organization org) {
        if (org == null
                || StringUtil.isBlankOrNull(org.getOrgName())
                || org.getOrgType() == null
                || org.getOrgProp() == null) {
            throw new BizException(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }

        setOrgParentIds(org);

        this.organizationMapper.insert(org);
        return APIResponse.returnSuccess(org);
    }


    @Override
    public APIResponse<Organization> updateById(Organization org) {

        if (org == null || org.getId() == null) {
            throw new BizException(ApiResponseEnum.PARAMETER_CANT_BE_EMPTY);
        }

        Organization persist = this.organizationMapper.selectByPrimaryKey(org.getId());
        if (persist == null) {
            throw new BizException(ApiResponseEnum.RECORD_DO_NOT_EXISTS);
        }

        if (persist.getParentId().longValue() != org.getParentId().longValue()) {
            setOrgParentIds(org);
        }

        this.organizationMapper.updateByPrimaryKeySelective(org);
        return APIResponse.returnSuccess(org);
    }

    @Override
    public APIResponse<Organization> get(Long id) {
        Organization organization = this.organizationMapper.selectByPrimaryKey(id);
        return APIResponse.returnSuccess(organization);
    }

    @Override
    public APIResponse<ApiResponseEnum> delete(Long id) {

        //机构下存在机构. 不允许删除.
        OrganizationExample organizationExample = new OrganizationExample();
        OrganizationExample.Criteria criteria = organizationExample.createCriteria();
        criteria.andParentIdEqualTo(id);

        int count = this.organizationMapper.countByExample(organizationExample);
        if (count > 0) {
            throw new BizException(ApiResponseEnum.HAVE_ENABLE_CHILDREN);
        }

        //机构下存在用户, 不允许删除.
        OrgUserExample orgUserExample = new OrgUserExample();
        OrgUserExample.Criteria orgUserCriteria = orgUserExample.createCriteria();
        orgUserCriteria.andOrgIdEqualTo(id);
        int member = this.orgUserMapper.countByExample(orgUserExample);
        if (member > 0) {
            throw new BizException(ApiResponseEnum.HAVE_ENABLE_CHILDREN);
        }

        Organization organization = new Organization();
        organization.setId(id);
        organization.setIsDelete(Constants.IS_DELETE_TRUE);

        this.organizationMapper.updateByPrimaryKeySelective(organization);
        return APIResponse.returnSuccess(ApiResponseEnum.SUCCESS);
    }

    @Override
    public APIResponse<PageObj<List<Organization>>> queryPageList(Organization org, int pageNum, int pageSize) {

        OrganizationExample organizationExample = new OrganizationExample();
        OrganizationExample.Criteria orgCriteria = organizationExample.createCriteria();

        if (org != null) {
            if (!StringUtil.isBlankOrNull(org.getOrgName())) {
                orgCriteria.andOrgNameLike("%" + org.getOrgName() + "%");
            }
            if (org.getOrgProp() != null) {
                orgCriteria.andOrgPropEqualTo(org.getOrgProp());
            }
            if (org.getOrgType() != null) {
                orgCriteria.andOrgTypeEqualTo(org.getOrgType());
            }
            if (org.getParentId() != null) {
                orgCriteria.andParentIdEqualTo(org.getParentId());
            }
        }

        return getPageObjAPIResponse(pageNum, pageSize, organizationExample);
    }


    @Override
    public APIResponse<PageObj<List<Organization>>> queryOrgList(Long parentId, boolean full) {

        OrganizationExample organizationExample = new OrganizationExample();
        OrganizationExample.Criteria orgCriteria = organizationExample.createCriteria();

        if (full) {
            orgCriteria.andParentIdsLike("%" + parentId + ",%");
        } else {
            orgCriteria.andParentIdEqualTo(parentId);
        }

        return getPageObjAPIResponse(1, 1000, organizationExample);
    }


    private APIResponse<PageObj<List<Organization>>> getPageObjAPIResponse(int pageNum, int pageSize, OrganizationExample organizationExample) {
        int total = this.organizationMapper.countByExample(organizationExample);
        if (total == 0) {
            return APIResponse.returnFail(ApiResponseEnum.DO_NOT_HAVE_ANY_MORE_RECORD);
        }

        Page page = Page.createPage(total, pageNum, pageSize);
        organizationExample.setPage(page);
        organizationExample.setOrderByClause(" priority asc ");
        List<Organization> list = this.organizationMapper.selectByExample(organizationExample);

        PageObj<List<Organization>> pageObj = PageObj.create(list, page);
        return APIResponse.returnSuccess(pageObj);
    }

    private void setOrgParentIds(Organization org) {
        Date now = new Date();
        org.setUpdateTime(now);
        if (org.getParentId() == null) {
            org.setParentId(0L);
            org.setParentIds("0");
            org.setCreateTime(now);
        } else {
            Organization parentOrg = new Organization();
            StringBuffer stringBuffer = new StringBuffer(org.getParentId() + ",");
            do {
                if (parentOrg != null) {
                    stringBuffer.append(parentOrg.getParentId() + ",");
                }
                parentOrg = get(org.getParentId()).getData();
            } while (parentOrg != null);
            org.setParentIds(stringBuffer.toString());
        }

    }
}
